package viper.receiver;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;

import viper.main.StateManager;

/**
 * @author Kevin Sin
 * 
 * Revision number: 3
 * Date created: 3/21/10
 * Date of Last Back-up on SVN: 3/21/10
 * 
 * <p>This class is a low-level class that just provides a 
 * method to receive UDP packets through the port specified in 
 * StateManager and to parse it.  Upon receiving a packet, it creates
 * a new UDPReceiverWorker thread to handle the packet so it is 
 * never gets backed up.
 */
public class UDPReceiver implements Runnable {

	public final static int MAX_PACKET_SIZE = 500; 
	
	private DatagramPacket packet;
	private DatagramSocket sock;
	private ExecutorService serv;
	private boolean running;
	
	public UDPReceiver(){
		running = true;
	}
	
	@Override
	public void run() {
		sock = StateManager.INSTANCE.getDatagramSocket();
		serv = StateManager.INSTANCE.getPool();
		
		//Continuously receive packets while logged in to program
		while(StateManager.INSTANCE.getState()!=StateManager.State.LOGGED_OUT && running)
		{
			try 
			{
				if(running){ //redundant check here to prevent socket exceptions on late processed threads
					packet = new DatagramPacket(new byte[MAX_PACKET_SIZE], MAX_PACKET_SIZE);
					sock.receive(packet);
					serv.execute(new UDPReceiverWorker(packet));
				}
			}catch(RejectedExecutionException ree){
				ree.printStackTrace();
				System.out.println("RejectedExecutionException in UDPReceiver.run().");
			}catch(SocketException e) {
				e.printStackTrace();
			}catch(IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void end(){
		running = false;
	}

}
